package com.santiao.youxiang.ui.fragment;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.recyclerview.widget.LinearLayoutManager;


import com.santiao.youxiang.MyPreferences;
import com.santiao.youxiang.R;
import com.santiao.youxiang.bean.History;
import com.santiao.youxiang.calculator.Calculator;
import com.santiao.youxiang.calculator.CalculatorKt;
import com.santiao.youxiang.calculator.parser.Expression;
//import com.santiao.youxiang.databinding.FragmentCalculatorBinding;
import com.santiao.youxiang.ui.adapter.HistoryAdapter;
import com.santiao.calculator.calculator.parser.NumberFormatter;
import com.santiao.youxiang.databinding.FragmentCalculatorBinding;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

public class CalculatorViewModel extends AndroidViewModel {
    Calculator calculatorKt = new Calculator(100);
    String groupingSeparatorSymbol = ",";
    String decimalSeparatorSymbol = ".";
    boolean isEqualLastAction = false;
    FragmentCalculatorBinding binding;

    Context context;
    MutableLiveData<String> EditTextValue = new MutableLiveData<>();
    MutableLiveData<BigDecimal> result = new MutableLiveData<>();
    private String lastHistoryElementId = "";
    private boolean isInvButtonClicked = false;
    private boolean isSound = true;
    private boolean isVibrate = true;
    private boolean errorStatusOld = false;
    HistoryAdapter historyAdapter;
    private boolean isStillTheSameCalculation_autoSaveCalculationWithoutEqualOption = false;
    private
    BigDecimal calculationResult = BigDecimal.ZERO;

    public CalculatorViewModel(@NonNull Application application) {
        super(application);
        context = application;

        historyAdapter=new HistoryAdapter(new ArrayList<>(),context);
    }

    public void setBinding(FragmentCalculatorBinding binding) {
        this.binding = binding;
        binding.historyRecylcleView.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false));
        binding.historyRecylcleView.setAdapter(historyAdapter);
    }

    public MutableLiveData<BigDecimal> getResult() {
        return result;
    }

    public MutableLiveData<String> getEditTextValue() {
        return EditTextValue;
    }

    public void cs() {

    }

    public void updateEdit(EditText view, String value) {

        // 去掉分隔符
        String valueNoSeparators = value.replace(groupingSeparatorSymbol, "");
        // 检查值是否为整数
        boolean isValueInt = valueNoSeparators.matches("-?\\d+");

        // 如果上一个操作是等号，重置输入框内容
        if (isEqualLastAction) {
            if (isValueInt || value.equals(decimalSeparatorSymbol)) {
                view.setText("");
            } else {
                view.setSelection(view.getText().length());
//               viewHorizontalScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
            }
            isEqualLastAction = false;
        }

        // 如果光标不可见，设置为可见
        if (!view.isCursorVisible()) {
            view.setCursorVisible(true);
        }

        String formerValue = view.getText().toString();
        int cursorPosition = view.getSelectionStart();
        String leftValue = formerValue.subSequence(0, cursorPosition).toString();
        String leftValueFormatted = NumberFormatter.INSTANCE.format(leftValue, decimalSeparatorSymbol, groupingSeparatorSymbol);
        String rightValue = formerValue.subSequence(cursorPosition, formerValue.length()).toString();
        String newValue = leftValue + value + rightValue;
        String newValueFormatted = NumberFormatter.INSTANCE.format(newValue, decimalSeparatorSymbol, groupingSeparatorSymbol);
        // 在主线程上更新UI
        // 防止在同一个数字中输入多个小数点
        if (value.equals(decimalSeparatorSymbol) && binding.input.getText().toString().contains(decimalSeparatorSymbol)) {
            if (!binding.input.getText().toString().isEmpty()) {
                String lastNumberBefore = "";
                if (cursorPosition > 0 && "0123456789".contains(Character.toString(binding.input.getText().toString().charAt(cursorPosition - 1))) || binding.input.getText().toString().substring(0, cursorPosition).contains(decimalSeparatorSymbol)) {
                    lastNumberBefore = NumberFormatter.INSTANCE.extractNumbers(
                            binding.input.getText().toString().substring(0, cursorPosition),
                            decimalSeparatorSymbol
                    ).get(NumberFormatter.INSTANCE.extractNumbers(
                            binding.input.getText().toString().substring(0, cursorPosition),
                            decimalSeparatorSymbol
                    ).size() - 1);
                }

                String firstNumberAfter = "";
                if (cursorPosition < binding.input.getText().length() - 1) {
                    firstNumberAfter = NumberFormatter.INSTANCE.extractNumbers(
                            binding.input.getText().toString().substring(cursorPosition, binding.input.getText().length()),
                            decimalSeparatorSymbol
                    ).get(0);
                }

                if (lastNumberBefore.contains(decimalSeparatorSymbol) || firstNumberAfter.contains(decimalSeparatorSymbol)) {
                    return;
                }
            }
        }


        Log.d("TAG", "4" + newValueFormatted);
        // 更新显示
        view.setText(newValueFormatted);

        // 设置光标位置
        if (isValueInt) {
            int cursorOffset = newValueFormatted.length() - newValue.length();
            view.setSelection(cursorPosition + value.length() + cursorOffset);
        } else {
            view.setSelection(leftValueFormatted.length() + value.length());
        }

//        newValueFormatted=newValueFormatted.replace("×","*");
//        newValueFormatted=newValueFormatted.replace("÷","/");

        Expression expression = new Expression();
        valueNoSeparators = expression.getCleanExpression(view.getText().toString(), decimalSeparatorSymbol, groupingSeparatorSymbol);
        if (!valueNoSeparators.isEmpty()) {
            CalculatorKt.set_infinity(false);
            CalculatorKt.setDomain_error(false);
            CalculatorKt.setDivision_by_0(false);
            CalculatorKt.setSyntax_error(false);
            CalculatorKt.setRequire_real_number(false);

        }
        setErrorColor(false, view, binding.resultDisplay);
        BigDecimal jg = calculatorKt.evaluate(valueNoSeparators, false);
        Log.d("TAG", valueNoSeparators + "," + jg + "," + CalculatorKt.getSyntax_error());
        getResult().setValue(jg);


    }

    @SuppressLint("SetTextI18n")
    public void addSymbol(EditText view, String currentSymbol) {
        // 获取输入文本的长度
        int textLength = view.getText().length();

        // 如果输入框不为空
        if (textLength > 0) {
            // 获取光标的当前位置
            int cursorPosition = view.getSelectionStart();

            // 获取光标位置相对的前后字符
            String nextChar = (textLength - cursorPosition > 0) ?
                    view.getText().charAt(cursorPosition) + "" : "0"; // 如果没有字符则默认返回"0"
            String previousChar = (cursorPosition > 0) ?
                    view.getText().charAt(cursorPosition - 1) + "" : "0";

            if (!currentSymbol.equals(previousChar) // 忽略重复按下的相同按钮
                    && !currentSymbol.equals(nextChar)
                    && !"√".equals(previousChar) // 在平方根开头不能添加符号
                    && !previousChar.equals(decimalSeparatorSymbol) // 确保前一个字符不是逗号
                    && (!"(".equals(previousChar) // 确保我们不在括号的开头
                    || "-".equals(currentSymbol))) { // 减号是覆盖符

                // 如果前一个字符是符号，则替换它
                if (previousChar.matches("[+\\-÷×^]")) {

                    String leftString = view.getText().subSequence(0, cursorPosition - 1).toString();
                    String rightString = view.getText().subSequence(cursorPosition, textLength).toString();

                    // 如果前一个符号是 + 或 -，在它们之前添加一个括号
                    if ("-".equals(currentSymbol)) {
                        if ("+".equals(previousChar) || "-".equals(previousChar)) {
                            view.setText(leftString + currentSymbol + rightString);
                            view.setSelection(cursorPosition);
                        } else {
                            view.setText(leftString + previousChar + currentSymbol + rightString);
                            view.setSelection(cursorPosition + 1);
                        }
                    } else if (cursorPosition > 1 && view.getText().charAt(cursorPosition - 2) != '(') {
                        view.setText(leftString + currentSymbol + rightString);
                        view.setSelection(cursorPosition);
                    } else if ("+".equals(currentSymbol)) {
                        view.setText(leftString + rightString);
                        view.setSelection(cursorPosition - 1);
                    }
                }
                // 如果下一个字符是符号，则替换它
                else if (nextChar.matches("[+\\-÷×^%!]")
                        && !"%".equals(currentSymbol)) { // 确保百分比符号不会替换后续的符号

                    String leftString = view.getText().subSequence(0, cursorPosition).toString();
                    String rightString = view.getText().subSequence(cursorPosition + 1, textLength).toString();

                    if (cursorPosition > 0 && !"(".equals(previousChar)) {
                        view.setText(leftString + currentSymbol + rightString);
                        view.setSelection(cursorPosition + 1);
                    } else if ("+".equals(currentSymbol)) {
                        view.setText(leftString + rightString);
                    }

                }
                // 否则直接更新显示
                else if (cursorPosition > 0 || !"0".equals(nextChar) && "-".equals(currentSymbol)) {
                    updateEdit(view, currentSymbol);
                } else {
                }
            } else {
            }
        } else { // 允许在输入为空时输入减号
            if ("-".equals(currentSymbol)) {
                updateEdit(view, currentSymbol);
            } else {
            }
        }
    }

    public void Ac(EditText input, TextView result) {
        input.setText("");
        result.setText("");
    }

    @SuppressLint("SetTextI18n")
    public void equalsButton(EditText input, TextView resultDisplay) {
        String calculation = input.getText().toString();

        if (!calculation.isEmpty()) {
            String resultString = resultDisplay.getText().toString();
            String formattedResult = NumberFormatter.INSTANCE.format(
                    resultString.replace(".", decimalSeparatorSymbol),
                    decimalSeparatorSymbol,
                    groupingSeparatorSymbol
            );
            // 检查结果是否是一个有限的数字
            if (!(CalculatorKt.getDivision_by_0() || CalculatorKt.getDomain_error() || CalculatorKt.getSyntax_error() || CalculatorKt.is_infinity() || CalculatorKt.getRequire_real_number())) {
                // 去掉结果中小数点后的多余零
                String[] resultSplited = resultString.split("\\.");
                if (resultSplited.length > 1) {
                    String resultPartAfterDecimalSeparator = resultSplited[1].replaceAll("0+$", "");
                    String resultWithoutZeros = resultSplited[0];
                    if (!resultPartAfterDecimalSeparator.isEmpty()) {
                        resultWithoutZeros = resultSplited[0] + "." + resultPartAfterDecimalSeparator;
                    }
                    formattedResult = NumberFormatter.INSTANCE.format(
                            resultWithoutZeros.replace(".", decimalSeparatorSymbol),
                            decimalSeparatorSymbol,
                            groupingSeparatorSymbol
                    );
                }

                // 如果计算结果与之前不同
                if (!calculation.equals(formattedResult)) {
                    List<History> history = new MyPreferences(context).getHistory();

                    if (isStillTheSameCalculation_autoSaveCalculationWithoutEqualOption) {
                        // 如果与之前的计算相同
                        // 获取之前的计算记录并更新
                        History previousHistoryElement = new MyPreferences(context).getHistoryElementById(lastHistoryElementId);
                        if (previousHistoryElement != null) {
                            previousHistoryElement.setCalculation(calculation);
                            previousHistoryElement.setResult(formattedResult);
                            previousHistoryElement.setTime(String.valueOf(System.currentTimeMillis()));
                            new MyPreferences(context).updateHistoryElementById(context, lastHistoryElementId, previousHistoryElement);

                            // 更新UI中的历史记录
                            historyAdapter.updateHistoryElement(previousHistoryElement);

                        }
                    } else {
                        // 如果是一个新的计算

                        // 获取当前时间
                        String currentTime = String.valueOf(System.currentTimeMillis());

                        // 保存到历史记录
                        String historyElementId = UUID.randomUUID().toString();
                        history.add(new History(calculation, formattedResult, currentTime, historyElementId));

                        lastHistoryElementId = historyElementId;
                        isStillTheSameCalculation_autoSaveCalculationWithoutEqualOption = true;

                        new MyPreferences(context).saveHistory(context, history);
                        // 更新UI中的历史记录
                        historyAdapter.appendOneHistoryElement(new History(calculation, formattedResult, currentTime, UUID.randomUUID().toString()));
                        // 移除多余的历史记录，保持历史记录数量在设定范围内
                        int historySize = Integer.parseInt(new MyPreferences(context).
                        getHistorySize());
                        while (historySize != -1 && historyAdapter.getItemCount() >= historySize && historyAdapter.getItemCount() > 0) {
                            historyAdapter.removeFirstHistoryElement();
                        }
                        // 滚动到RecycleView的底部以显示最新的历史记录
                        binding.historyRecylcleView.scrollToPosition(historyAdapter.getItemCount() - 1);

                    }
                }


                // 隐藏光标
                input.setCursorVisible(false);

                // 显示结果
                input.setText(formattedResult);

                // 设置光标
                input.setSelection(input.length());
                input.setCursorVisible(false); // 隐藏光标

                // 清空结果显示区域
                resultDisplay.setText("");

//                if (!calculation.equals(formattedResult)) {
//                    List<History> history = MyPreferences.this.getHistory();
//
//                    isStillTheSameCalculation_autoSaveCalculationWithoutEqualOption = false;
//
//                    // 如果上次记录与当前记录不同，则保存到历史记录
//                    if (history.isEmpty() || !history.get(history.size() - 1).getCalculation().equals(calculation)) {
//                        // 存储当前时间
//                        String currentTime = String.valueOf(System.currentTimeMillis());
//
//                        // 保存到历史记录
//                        String historyElementId = UUID.randomUUID().toString();
//                        history.add(new History(calculation, formattedResult, currentTime, historyElementId));
//
//                        MyPreferences.this.saveHistory(MainActivity.this, history);
//
//                        lastHistoryElementId = historyElementId;
//
//                        // 更新 UI 中的历史记录变量
//                        historyAdapter.appendOneHistoryElement(new History(
//                                calculation, formattedResult, currentTime, UUID.randomUUID().toString()
//                        ));
//
//                        // 如果历史记录超过 historySize 的偏好设置，则移除以前的记录
//                        int historySize = Integer.parseInt(MyPreferences.this.historySize);
//                        while (historySize != -1 && historyAdapter.getItemCount() >= historySize && historyAdapter.getItemCount() > 0) {
//                            historyAdapter.removeFirstHistoryElement();
//                        }
//
//                        // 滚动到历史记录视图的底部
//                        historyRecylcleView.scrollToPosition(historyAdapter.getItemCount() - 1);
//                    }
//                }
                isEqualLastAction = true;
            } else {
                if (CalculatorKt.getSyntax_error()) {
                    setErrorColor(true, input, resultDisplay);
                    resultDisplay.setText(context.getString(R.string.syntax_error));
                } else if (CalculatorKt.getDomain_error()) {
                    setErrorColor(true, input, resultDisplay);
                    resultDisplay.setText(context.getString(R.string.domain_error));
                } else if (CalculatorKt.getRequire_real_number()) {
                    setErrorColor(true, input, resultDisplay);
                    resultDisplay.setText(context.getString(R.string.require_real_number));
                } else if (CalculatorKt.getDivision_by_0()) {
                    setErrorColor(true, input, resultDisplay);
                    resultDisplay.setText(context.getString(R.string.division_by_0));
                } else if (CalculatorKt.is_infinity()) {
                    if (calculationResult.compareTo(BigDecimal.ZERO) < 0) {
                        resultDisplay.setText("-" + context.getString(R.string.infinity));
                    } else {
                        resultDisplay.setText(context.getString(R.string.value_too_large));
                    }
                } else {
                    resultDisplay.setText(formattedResult);
                    isEqualLastAction = true; // 如果出现错误，单击数字时不要清除计算
                }
            }

        } else {
            resultDisplay.setText("");
        }
    }

    private void setErrorColor(final boolean errorStatus, EditText input, TextView resultDisplay) {
        // 确保在UI线程中运行

        // 只有在颜色需要更新时才运行
        if (errorStatus != errorStatusOld) {
            // 设置错误颜色
            if (errorStatus) {
                input.setTextColor(
                        ContextCompat.getColor(
                                context,
                                R.color.calculation_error_color
                        )
                );
                resultDisplay.setTextColor(
                        ContextCompat.getColor(
                                context,
                                R.color.calculation_error_color
                        )
                );
            }
            // 清除错误颜色
            else {
                input.setTextColor(ContextCompat.getColor(context, R.color.history_background_color));
                resultDisplay.setTextColor(
                        ContextCompat.getColor(
                                context,
                                R.color.amoled_button_ripple_color
                        )
                );
            }
            errorStatusOld = errorStatus;
        }

    }


    public void enableOrDisableScientistMode() {
        if (binding.scientistModeRow2.getVisibility() != View.VISIBLE) {
            binding.scientistModeRow2.setVisibility(View.VISIBLE);
            binding.scientistModeRow3.setVisibility(View.VISIBLE);
            binding.scientistModeSwitchButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_up_24);
            binding.degreeTextView.setVisibility(View.VISIBLE);
            binding.degreeTextView.setText(binding.degreeButton.getText().toString());
        } else {
            binding.scientistModeRow2.setVisibility(View.GONE);
            binding.scientistModeRow3.setVisibility(View.GONE);
            binding.scientistModeSwitchButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_down_24);
            binding.degreeTextView.setVisibility(View.GONE);
            binding.degreeTextView.setText(binding.degreeButton.getText().toString());
        }
    }

    public void parenthesesButton(EditText view) {
        int cursorPosition = binding.input.getSelectionStart();
        int textLength = binding.input.getText().length();

        int openParentheses = 0;
        int closeParentheses = 0;

        String text = binding.input.getText().toString();

        for (int i = 0; i < cursorPosition; i++) {
            if (text.charAt(i) == '(') {
                openParentheses++;
            }
            if (text.charAt(i) == ')') {
                closeParentheses++;
            }
        }

        if (!(textLength > cursorPosition && "×÷+-^".indexOf(binding.input.getText().toString().charAt(cursorPosition)) != -1) &&
                (openParentheses == closeParentheses
                        || binding.input.getText().toString().charAt(cursorPosition - 1) == '('
                        || "×÷+-^".indexOf(binding.input.getText().toString().charAt(cursorPosition - 1)) != -1)) {
            updateEdit(view, "(");
        } else {
            updateEdit(view, ")");
        }
    }

    public void sineButton(EditText view) {
        if (!isInvButtonClicked) {
            updateEdit(view, "sin(");
        } else {
            updateEdit(view, "sin⁻¹(");
        }
    }

    public void cosineButton(EditText view) {
        if (!isInvButtonClicked) {
            updateEdit(view, "cos(");
        } else {
            updateEdit(view, "cos⁻¹(");
        }
    }

    public void tangentButton(EditText view) {
        if (!isInvButtonClicked) {
            updateEdit(view, "tan(");
        } else {
            updateEdit(view, "tan⁻¹(");
        }
    }

    public void naturalLogarithmButton(EditText view) {
        if (!isInvButtonClicked) {
            updateEdit(view, "ln(");
        } else {
            updateEdit(view, "exp(");
        }
    }

    public void logarithmButton(EditText view) {
        if (!isInvButtonClicked) {
            updateEdit(view, "log(");
        } else {
            updateEdit(view, "10^");
        }
    }

    public void backspaceButton() {
        int cursorPosition = binding.input.getSelectionStart();
        int textLength = binding.input.getText().length();
        String newValue = "";
        boolean isFunction = false;
        boolean isDecimal = false;
        int functionLength = 0;

        if (isEqualLastAction) {
            cursorPosition = textLength;
        }

        if (cursorPosition != 0 && textLength != 0) {
            // 检查是否是需要删除的函数
            List<String> functionsList = Arrays.asList("cos⁻¹(", "sin⁻¹(", "tan⁻¹(", "cos(", "sin(", "tan(", "ln(", "log(", "exp(");
            for (String function : functionsList) {
                String leftPart = binding.input.getText().subSequence(0, cursorPosition).toString();
                if (leftPart.endsWith(function)) {
                    newValue = binding.input.getText().subSequence(0, cursorPosition - function.length()).toString() +
                            binding.input.getText().subSequence(cursorPosition, textLength).toString();
                    isFunction = true;
                    functionLength = function.length() - 1;
                    break;
                }
            }

            // 如果不是函数
            if (!isFunction) {
                // 移除分组符号
                String leftPart = binding.input.getText().subSequence(0, cursorPosition).toString();
                String leftPartWithoutSpaces = leftPart.replace(groupingSeparatorSymbol, "");
                functionLength = leftPart.length() - leftPartWithoutSpaces.length();

                newValue = leftPartWithoutSpaces.subSequence(0, leftPartWithoutSpaces.length() - 1).toString() +
                        binding.input.getText().subSequence(cursorPosition, textLength).toString();

                isDecimal = binding.input.getText().charAt(cursorPosition - 1) == decimalSeparatorSymbol.charAt(0);
            }

            // 当删除小数点时，特殊处理光标位置
            int rightSideCommas = 0;
            if (isDecimal) {
                CharSequence oldString = binding.input.getText();
                int immediateRightDigits = 0;
                int index = cursorPosition;

                // 找出之前在小数点右侧的数字数量
                while (index < textLength && Character.isDigit(oldString.charAt(index))) {
                    index++;
                    immediateRightDigits++;
                }

                // 确定有多少个千位分隔符在右侧
                if (immediateRightDigits > 3) {
                    rightSideCommas = immediateRightDigits / 3;
                }
            }

            String newValueFormatted = NumberFormatter.INSTANCE.format(newValue, decimalSeparatorSymbol, groupingSeparatorSymbol);
            int cursorOffset = newValueFormatted.length() - newValue.length() - rightSideCommas;
            if (cursorOffset < 0) cursorOffset = 0;

            binding.input.setText(newValueFormatted);
            binding.input.setSelection(Math.max(cursorPosition - 1 + cursorOffset - functionLength, 0));
        }
    }

    public void invButton() {

        if (!isInvButtonClicked) {
            isInvButtonClicked = true;

            // 改变按钮文本
            binding.sineButton.setText(R.string.sineInv);
            binding.cosineButton.setText(R.string.cosineInv);
            binding.tangentButton.setText(R.string.tangentInv);
            binding.naturalLogarithmButton.setText(R.string.naturalLogarithmInv);
            binding.logarithmButton.setText(R.string.logarithmInv);
//
//            if (new MyPreferences(this).addModuloButton()) {
//                binding.squareButton.setText(R.string.squareInvModuloVersion);
//            } else {
//                binding.squareButton.setText(R.string.squareInv);
//            }

        } else {
            isInvButtonClicked = false;

            // 恢复按钮文本
            binding.sineButton.setText(R.string.sine);
            binding.cosineButton.setText(R.string.cosine);
            binding.tangentButton.setText(R.string.tangent);
            binding.naturalLogarithmButton.setText(R.string.naturalLogarithm);
            binding.logarithmButton.setText(R.string.logarithm);
            binding.squareButton.setText(R.string.square);
        }
    }





}
